<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\finance;

use app\service\BaseService;
use app\service\finance\statement\StatementService;

final class AccountRangeService extends BaseService
{
    private ?StatementService $statement;

    public function __construct(StatementService $statementService)
    {
        $this->statement = $statementService;
    }

    public function isValid(): bool
    {
        return true;
    }

    /**
     * 生成时间轴.
     */
    public function beRange(): array
    {
        $timeRange = createDateRange($this->statement->startDate, $this->statement->endDate, 'Ymd');
        $result = [];
        foreach ($timeRange as $day) {
            $day = intval($day);
            $result[] = [
                'account_type' => $this->getType($day),
                'port_id' => $this->getPort($day),
                'service_id' => $this->getService($day),
                'date' => $day,
            ];
        }
        return $this->filterRange($result);
    }

    /**
     * 过滤时间轴格式.
     * @param array $range 分日时间轴
     */
    private function filterRange(array $range = []): array
    {
        $data = [];
        $keyPre = '';
        foreach ($range as $k => $item) {
            $key = $item['account_type'] . '_' . $item['port_id'] . '_' . $item['service_id'];
            if (isset($data[$key])) {
                if ($key == $keyPre) {
                    $dateIndex = count($data[$key]['date_range']) - 1;
                    $data[$key]['date_range'][$dateIndex]['end_date'] = $item['date'];
                } else {
                    $data[$key]['date_range'][]['start_date'] = $item['date'];
                    if (! isset($range[$k + 1])) {
                        $data[$key]['date_range'][0]['end_date'] = $item['date'];
                    }
                }
            } else {
                $data[$key] = [
                    'account_type' => $item['account_type'],
                    'port_id' => $item['port_id'],
                    'date_range' => [
                        ['start_date' => $item['date']],
                    ],
                ];
                $data[$key]['provider_id'] = 0;
                $data[$key]['provider_service_type'] = 0;
                $data[$key]['provider_service_id'] = 0;
                if ($item['service_id']) {
                    $provider = explode('_', $item['service_id']);
                    $data[$key]['provider_id'] = $provider[2] ?? 0;
                    $data[$key]['provider_service_type'] = $provider[1] ?? 0;
                    $data[$key]['provider_service_id'] = $provider[0] ?? 0;
                }
                if (! isset($range[$k + 1])) {
                    $data[$key]['date_range'][0]['end_date'] = $item['date'];
                }
            }
            $keyPre = $key;
        }
        return array_values($data);
    }

    /**
     * 获取类型.
     * @param int $day 日
     * @return int|mixed
     */
    private function getType(int $day = 0)
    {
        foreach ($this->statement->getTypeRange() as $item) {
            if ($day >= $item['start_date'] && $day <= $item['end_date']) {
                return $item['account_type'];
            }
        }
        return 0;
    }

    /**
     * 获取端口.
     * @param int $day 日
     * @return int|mixed
     */
    private function getPort(int $day = 0)
    {
        foreach ($this->statement->getPortRange() as $item) {
            if ($day >= $item['start_date'] && $day <= $item['end_date']) {
                return $item['port_id'];
            }
        }
        return 0;
    }

    /**
     * 获取服务.
     * @param int $day 日
     */
    private function getService(int $day = 0): string
    {
        foreach ($this->statement->getServiceRange() as $item) {
            if (($day >= $item['start_date'] && $day <= $item['end_date']) || ! $item['service_id']) {
                return $item['provider_id'] ? $item['service_id'] . '_' . $item['service_type'] . '_' . $item['provider_id'] : '';
            }
        }
        return '';
    }
}
